<template>
  <n-upload
    v-if="isShow"
    :list-type="isImg ? 'image-card' : 'text'"
    v-bind="$attrs"
    :action="uploadUrl"
    :accept="isImg && isAcceptType ? ImageType : undefined"
    :default-file-list="fileList"
    @finish="Finish"
    @remove="remove"
    @error="handleError"
  >
    <slot>
      <span v-if="isImg">上传图片</span>
      <n-button v-else>上传文件</n-button>
    </slot>
  </n-upload>
</template>
<script lang="ts" setup>
import {isArray} from '@/utils/is';
import {UploadFileInfo} from 'naive-ui';
import {nextTick, PropType, ref, watch} from 'vue';
import {ImageType} from '@/utils/file-type';
import {cloneDeep} from 'lodash';
import SlashAppContext from "@/context/SlashAppContext";
import {UploadResponse} from './type'

const props = defineProps({
  modelValue: {
    type: [Array, String],
    defalut: '',
  },
  fileList: {
    type: Array as PropType<UploadFileInfo[]>,
  },
  url: {
    type: String,
  },
  isImg: {
    type: String,
  },
  isAcceptType: {
    type: Boolean,
    default: true,
  },
});
const emits = defineEmits(['update:modelValue', 'update:fileList']);

const uploadUrl = SlashAppContext.getFileUploadUrl()
console.log("文件上传地址:", uploadUrl)
const fileBaseUrl = SlashAppContext.fileBaseUrl()

const isShow = ref(true);
const fileList = ref<UploadFileInfo[]>([]);
let isChange = false;

function Finish(data: { file: UploadFileInfo; event: any }) {
  const {file, event} = data;
  const response: UploadResponse | null =
    event.target?.response && JSON.parse(event.target.response);
  if (response) {
    isChange = true;
    /**存相对路径 */
    // const newFile = cloneDeep(file);
    file.url = fileBaseUrl + response.data[0].uri;
    fileList.value.push(file);
    const val = fileList.value.map((item) => item.url?.replace(fileBaseUrl, '')).join(',');
    emits('update:modelValue', val);
    emits('update:fileList', fileList.value);
  }
}

function remove(options: { file: UploadFileInfo; fileList: Array<UploadFileInfo>; event?: Event }) {
  console.log('remove');
  fileList.value = fileList.value.filter((item) => item.id !== options.file.id);
  /**删除文件时，无 */
  const val = fileList.value.map((item) => item.url?.replace(fileBaseUrl, '')).join(',');
  emits('update:modelValue', val);
  emits('update:fileList', fileList.value);
  console.log(val, options, fileList.value);
}

const getName = (str: string) => (str ? str.split('/').pop() : '');

function initFileList() {
  console.log(props.modelValue);
  if (isChange) return;
  if (props.fileList && props.fileList.length) {
    fileList.value = cloneDeep(props.fileList);
    return;
  }
  if (props.modelValue) {
    console.log('执行');
    /**强制更新组件 */
    isShow.value = false;
    const arr: string[] = isArray(props.modelValue)
      ? (props.modelValue as string[])
      : props.modelValue.split(',');
    fileList.value = arr.map((str, index) => ({
      id: index + '',
      name: getName(str),
      status: 'finished',
      url: fileBaseUrl + str,
    } as UploadFileInfo));
    /**强制更新组件 */
    nextTick(() => (isShow.value = true));
  }
}

function handleError() {
  (window as any).$message && (window as any).$message.error('上传失败');
}

watch(
  () => props.modelValue,
  () => {
    initFileList();
  },
  {
    immediate: true,
  }
);
defineExpose({
  fileList,
});
</script>
<style lang="less" scoped>
.class {
}
</style>
